package views

import (
	"encoding/json"
	"strings"

	"github.com/alecthomas/chroma/quick"
	tea "github.com/charmbracelet/bubbletea"
	"github.com/charmbracelet/lipgloss"
)

type Preview struct {
	Data   map[string]interface{}
	Parent *ScrollModel
}

func (m Preview) Init() tea.Cmd {
	return nil
}

func (m Preview) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
	switch msg := msg.(type) {
	case tea.KeyMsg:
		switch msg.String() {
		case "ctrl+c", "esc", "q":
			return m.Parent, nil
		}
	}
	return m, nil
}

var (
	defaultStyle = lipgloss.NewStyle().
		Bold(true).
		Foreground(lipgloss.Color("#FAFAFA")).
		Background(lipgloss.Color("#7D56F4")).
		PaddingTop(2).
		PaddingLeft(2)
)

func (m Preview) View() string {
	body := strings.Builder{}
	// format the data as json with tab
	marshal, err := json.MarshalIndent(m.Data, "", "  ")
	if err != nil {
		body.WriteString("not a valid json")
	} else {
		highlightedJSON := m.highlightJSON(string(marshal))
		body.WriteString(highlightedJSON)
	}
	return body.String()
}

func (m Preview) highlightJSON(jsonStr string) string {
	var highlighted strings.Builder

	// Parse the JSON string into a map
	var jsonData map[string]interface{}
	err := json.Unmarshal([]byte(jsonStr), &jsonData)
	if err != nil {
		return jsonStr // fallback to plain json if parsing fails
	}

	// Reformat the JSON data with indentation
	formattedJSON, err := json.MarshalIndent(jsonData, "", "  ")
	if err != nil {
		return jsonStr // fallback to plain json if formatting fails
	}

	// Highlight the formatted JSON string
	err = quick.Highlight(&highlighted, string(formattedJSON), "json", "terminal256", "fallback")
	if err != nil {
		return string(formattedJSON) // fallback to plain formatted json if highlighting fails
	}

	return highlighted.String()
}
